#include "config.h"

#include "usart.h"

#include "init.h"
#include "serial.h"
#include "buffers.h"
#include "shared.h"
#include "util.h"
#include "test.h"
#include "command.h"
#include "event.h"
#include "strings.h"

/*
clock:
Assume 10 MHz crystal oscillator input.

Vc --- LCD CONTRAST SETTING VOLTAGE ( 0 TO -7VDC)
 - PWM this?
Vlcd --- LCD MODULES V- VOLTAGE ( -7 TO -9VDC)
 - need to find negative voltage generator
 
CS1:RB3	low to enable u3
CS2:RB4	low to enable u4
CS3:RC1	high to enable u3 or u4, use in conjunction with CS1 & CS2
E:RB2		W: Data of DB0 to DB7 is latched at the fall of E
 		R: Data appears at DB0 to DB7 while E is at high level.
R/W:RB1	R = high, W = low
D/I:RB0	D = high, I = low
RST:RC0	active low, display off, display from line 0
DB7:RD7	MSB, busy flag active high when D/I = 0, R/W = 1
DB0:RD6	LSB

RC3:	LED

tBUSY:	between 1 and 3 LCD clock cycles (250 kHz?)
timing:	see page 30 of HD61202 datasheet

serial: no flow control, 8 bits, no parity, 
19.2 kBaud
asynchronous
sync = 0, brgh = 1, brg16 = 0, spbrg = 129
allows 2.3 fps

115.2 kBaud
asynchronous
sync = 0, brgh = 1, brg16=0, spbrg=21
or SYNC = 0, BRGH = 1, BRG16 = 1, spbrg = 86 for less error
allows 14.1 fps

from example code:
4ms delay: after init, after each command, but not after data writes
40us delay: not used
100us delay: not used
LongDelay (60ms): scrolling interval
*/

//#define lazyEcho	// repeat all received data

void low_isr(void);
void high_isr(void);

#pragma code high_isr_entry=0x8
void high_isr_entry(void){	_asm GOTO high_isr _endasm}

#pragma code low_isr_entry=0x18
void low_isr_entry(void){	_asm GOTO high_isr _endasm}

#pragma code
// use PIE1bits.TXIE as RTS variable.  To send something,
// set it to 1.

#pragma interrupt low_isr
void low_isr(void){
}

#pragma interrupt high_isr
void high_isr(void){
	char rcBufAlmostFull;
	if(PIR1bits.RCIF){
		PIR1bits.RCIF = 0;
		rcBufAlmostFull = receiveBufIns(RCREG);
#ifdef useFlowControl
		if(rcBufAlmostFull == 1 && !XOFFsent){
			while(!TXSTAbits.TRMT);
			TXREG = XOFF; // software flow control XOFF
			XOFFsent = 1;
		}
		else if(rcBufAlmostFull == 1 && XOFFsent){
			while(!TXSTAbits.TRMT);
			TXREG = '@';
		}
#endif
#ifdef lazyEcho
		if(TXSTAbits.TRMT) // if ready to fill transmit buffer
			TXREG = RCREG;
#endif
	}
	if(PIR2bits.CCP2IF){
		PIR2bits.CCP2IF = 0;
		msCount50++;
		if(msCount50 == 10){ // 500 ms
			PORTCbits.RC3 = secTick;
			msCount50 = 0;
			secTick = !secTick;
		}
		if(eventTimer){
			msCount50Event++;
			if(!--msCount50Event){
				eventTimer = 0;
			}
		}
	}
	if(PIE1bits.TXIE && PIR1bits.TXIF){
		// if more bytes to send, send next byte
		if(sendIndex < sendCount){
			TXREG = sendBuffer[sendIndex++];
		}else{	// if no more bytes, turn off TX interrupt
			PIE1bits.TXIE = 0;
			sendIndex = 0;
			sendCount = 0;
		}
	}
}

void main(void)
{
	unsigned char cmd;
	init();
//	putcUSART(' ');
//	Delay10KTCYx(10); // 100 ms
//	putsUSART(testString);
	CRLF();
	putrsUSART(welcomeString);
	CRLF();
	while(1){
		// process serial commands
		while(rcBufHead == rcBufTail);
		cmd = receiveBufRem();
		processCommand(cmd);
	}
}

